﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Xom.Generator;

namespace Xom.UnitTests.Generator
{
    [TestClass]
    public class BindingGeneratorTests
    {
        //[Ignore]
        [TestMethod]
        public void GenerateModelFromFile()
        {
            IList<XDocument> xsdFiles = new List<XDocument>();
            xsdFiles.Add(XDocument.Load(@"C:\Test\test.xsd", LoadOptions.SetBaseUri));

            BindingGenerator.Load(xsdFiles, "Xom.UnitTests.Generator", "");
        }

        [TestMethod]
        public void GenerateBatchModel()
        {
            //arrange
            IList<Stream> xsdFiles = new List<Stream>();
            xsdFiles.Add(new MemoryStream(Properties.Resources.batch));

            //act
            IList<string> result = BindingGenerator.Load(xsdFiles, "Xom.UnitTests.Generator");

            //assert
            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(false,string.IsNullOrEmpty(result[0]));
            Assert.IsTrue(result[0].Contains("interface IBatch"));
            Assert.IsTrue(result[0].Contains("interface IPurchaseOrder"));
            Assert.IsTrue(result[0].Contains("interface IItem"));
            Assert.IsTrue(result[0].Contains("/// Description of Batch"));
            Assert.IsTrue(result[0].Contains("/// Product Number"));
            Assert.IsTrue(result[0].Contains("class Batch"));
            Assert.IsTrue(result[0].Contains("class PurchaseOrder"));
            Assert.IsTrue(result[0].Contains("class Item"));
        }

        [TestMethod]
        public void GenerateCompanyModel()
        {
            //arrange
            IList<Stream> xsdFiles = new List<Stream>();
            xsdFiles.Add(new MemoryStream(Properties.Resources.Company));

            //act
            IList<string> result = BindingGenerator.Load(xsdFiles, "Xom.UnitTests.Generator");

            //assert
            Assert.IsNotNull(result);
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(false, string.IsNullOrEmpty(result[0]));
        }

        [TestMethod]
        public void ReadBatchXmlWithGeneratedClass()
        {
            //arrange
            XDocument doc = XDocument.Load(new MemoryStream(Properties.Resources.BatchXml));

            //act
            IBatch batch = XmlObjectMapper.Load(doc, typeof(Batch)) as IBatch;

            //assert
            Assert.IsNotNull(batch);
            Assert.AreEqual(2, batch.PurchaseOrders.Count);
            Assert.AreEqual("0815", batch.PurchaseOrders[0].CustId);
            Assert.AreEqual(2, batch.PurchaseOrders[0].Items.Count);
            Assert.AreEqual("1234", batch.PurchaseOrders[0].Items[0].ProdId);
            Assert.AreEqual(Convert.ToDouble(37), batch.PurchaseOrders[0].Items[0].Price);
            Assert.AreEqual(2, batch.PurchaseOrders[0].Items[0].Quantity);
        }

        [TestMethod]
        public void ReadCompanyXmlWithGeneratedClass()
        {
            //arrange
            XDocument doc = XDocument.Load(new MemoryStream(Properties.Resources.CompanyXml));

            //act
            ICompany company = XmlObjectMapper.Load(doc, typeof(Company)) as ICompany;

            //assert
            Assert.IsNotNull(company);
            Assert.AreEqual(1, company.Departments.Count);
            Assert.AreEqual(true, company.Departments[0].Label.Contains("The top department"));
            Assert.AreEqual(1,company.Departments[0].Deptno);
            Assert.IsNotNull(company.Departments[0].Manager);
            Assert.AreEqual("Merlin", company.Departments[0].Manager.Name);
            Assert.AreEqual(Convert.ToDouble(9999), company.Departments[0].Manager.Salary);
            Assert.IsNotNull(company.Departments[0].Members);
            Assert.AreEqual(2,company.Departments[0].Members.Count);
            Assert.AreEqual(true, company.Departments[0].Members[1].Department.Label.Contains("Development"));
            Assert.AreEqual(2, company.Departments[0].Members[1].Department.Members.Count);
            Assert.AreEqual("Donald", company.Departments[0].Members[1].Department.Members[0].Employee.Name);
            Assert.AreEqual(Convert.ToDouble(5555), company.Departments[0].Members[1].Department.Members[0].Employee.Salary);
        }
    }
}
